/**
 * 表单数据缓存服务
 * 用于在session过期时保存用户的表单数据
 */

import { AUTH_STORAGE_KEYS, FORM_CACHE_CONFIG } from '../config/authConfig';

interface CacheItem {
  data: any;
  timestamp: number;
  expireAt: number;
}

class FormCache {
  private getCacheKey(key: string): string {
    return `${AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX}${key}`;
  }

  /**
   * 保存表单数据
   * @param key 缓存键
   * @param data 表单数据
   */
  save(key: string, data: any): void {
    try {
      const timestamp = Date.now();
      const expireAt = timestamp + FORM_CACHE_CONFIG.EXPIRE_MINUTES * 60 * 1000;
      
      const cacheItem: CacheItem = {
        data,
        timestamp,
        expireAt
      };

      localStorage.setItem(this.getCacheKey(key), JSON.stringify(cacheItem));
      
      // 自动清理过期缓存
      if (FORM_CACHE_CONFIG.AUTO_CLEAN) {
        this.cleanExpired();
      }

      // 检查缓存数量限制
      this.checkCacheLimit();
    } catch (error) {
      console.error('保存表单缓存失败:', error);
    }
  }

  /**
   * 获取缓存的表单数据
   * @param key 缓存键
   * @returns 表单数据或null
   */
  get(key: string): any | null {
    try {
      const cacheKey = this.getCacheKey(key);
      const cached = localStorage.getItem(cacheKey);
      
      if (!cached) {
        return null;
      }

      const cacheItem: CacheItem = JSON.parse(cached);
      
      // 检查是否过期
      if (Date.now() > cacheItem.expireAt) {
        localStorage.removeItem(cacheKey);
        return null;
      }

      return cacheItem.data;
    } catch (error) {
      console.error('获取表单缓存失败:', error);
      return null;
    }
  }

  /**
   * 清除指定的缓存
   * @param key 缓存键
   */
  clear(key: string): void {
    try {
      localStorage.removeItem(this.getCacheKey(key));
    } catch (error) {
      console.error('清除表单缓存失败:', error);
    }
  }

  /**
   * 清除所有表单缓存
   */
  clearAll(): void {
    try {
      const keys = Object.keys(localStorage);
      keys.forEach(key => {
        if (key.startsWith(AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX)) {
          localStorage.removeItem(key);
        }
      });
    } catch (error) {
      console.error('清除所有表单缓存失败:', error);
    }
  }

  /**
   * 清理过期的缓存
   */
  private cleanExpired(): void {
    try {
      const keys = Object.keys(localStorage);
      const now = Date.now();
      
      keys.forEach(key => {
        if (key.startsWith(AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX)) {
          const cached = localStorage.getItem(key);
          if (cached) {
            try {
              const cacheItem: CacheItem = JSON.parse(cached);
              if (now > cacheItem.expireAt) {
                localStorage.removeItem(key);
              }
            } catch {
              // 如果解析失败，删除该项
              localStorage.removeItem(key);
            }
          }
        }
      });
    } catch (error) {
      console.error('清理过期缓存失败:', error);
    }
  }

  /**
   * 检查缓存数量限制
   */
  private checkCacheLimit(): void {
    try {
      const cacheKeys: string[] = [];
      const keys = Object.keys(localStorage);
      
      keys.forEach(key => {
        if (key.startsWith(AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX)) {
          cacheKeys.push(key);
        }
      });

      // 如果超过最大缓存数量，删除最旧的缓存
      if (cacheKeys.length > FORM_CACHE_CONFIG.MAX_CACHE_COUNT) {
        const cacheItems: Array<{ key: string; timestamp: number }> = [];
        
        cacheKeys.forEach(key => {
          const cached = localStorage.getItem(key);
          if (cached) {
            try {
              const cacheItem: CacheItem = JSON.parse(cached);
              cacheItems.push({ key, timestamp: cacheItem.timestamp });
            } catch {
              // 解析失败的直接删除
              localStorage.removeItem(key);
            }
          }
        });

        // 按时间戳排序，删除最旧的
        cacheItems.sort((a, b) => a.timestamp - b.timestamp);
        const itemsToRemove = cacheItems.length - FORM_CACHE_CONFIG.MAX_CACHE_COUNT;
        
        for (let i = 0; i < itemsToRemove; i++) {
          localStorage.removeItem(cacheItems[i].key);
        }
      }
    } catch (error) {
      console.error('检查缓存数量限制失败:', error);
    }
  }

  /**
   * 检查是否有缓存的表单数据
   * @param key 缓存键
   * @returns boolean
   */
  has(key: string): boolean {
    return this.get(key) !== null;
  }

  /**
   * 获取所有缓存的键
   * @returns 缓存键数组
   */
  getAllKeys(): string[] {
    const cacheKeys: string[] = [];
    const keys = Object.keys(localStorage);
    
    keys.forEach(key => {
      if (key.startsWith(AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX)) {
        const actualKey = key.replace(AUTH_STORAGE_KEYS.FORM_CACHE_PREFIX, '');
        if (this.get(actualKey) !== null) {
          cacheKeys.push(actualKey);
        }
      }
    });

    return cacheKeys;
  }
}

// 导出单例实例
export const formCache = new FormCache();

// 导出类以便测试
export default FormCache;